package com.brtbeacon.wx.demo.mapview;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.widget.FrameLayout;

import com.brtbeacon.wx.map.v2.BRTWebViewPlugin;
import com.brtbeacon.wx.map.v2.DefaultWebViewX5Delegate;
import com.tencent.smtt.export.external.interfaces.GeolocationPermissionsCallback;
import com.tencent.smtt.export.external.interfaces.PermissionRequest;
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import java.util.ArrayList;
import java.util.List;

public class MapWebViewX5PluginActivity extends AppCompatActivity {

    public static final String TAG = MapWebViewX5PluginActivity.class.getSimpleName();
    public static final  String PARAM_URL = "param_url";
    private static final int REQUEST_PLUGIN_PERMISSIONS = 1;
    private static final int REQUEST_ENABLE_BT = 1001;
    private static final int REQUEST_ENABLE_GPS = 1002;

    private FrameLayout rootView;
    private WebView webView;
    private BRTWebViewPlugin webViewPlugin;
    private String url;

    public static void startActivity(Context ctxt, String url) {
        Intent intent = new Intent(ctxt, MapWebViewX5PluginActivity.class);
        intent.putExtra(PARAM_URL, url);
        ctxt.startActivity(intent);
    }

    @SuppressLint("JavascriptInterface")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view_x5_plugin);
        rootView = findViewById(R.id.rootView);

        url = getIntent().getStringExtra(PARAM_URL);
        if (TextUtils.isEmpty(url)) {
            url = "";
        }

        IntentFilter statusFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(btStateBroadcastReceive, statusFilter);

        //  检查权限
        checkPermissions();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(btStateBroadcastReceive);
        if (webViewPlugin != null) {
            webViewPlugin.onDestroy();
        }
    }

    /**
     * 初始化X5引擎内核
     */
    private void initX5() {
        //搜集本地tbs内核信息并上报服务器，服务器返回结果决定使用哪个内核。
        QbSdk.setDownloadWithoutWifi(true);
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(final boolean result) {
                //x5內核初始化完成的回调，为true表示x5内核加载成功，否则表示x5内核加载失败，会自动切换到系统内核。
                Log.d("app", " onViewInitFinished is " + result);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        createWebView();
                    }
                });
            }

            @Override
            public void onCoreInitFinished() {
                Log.d("app", " onCoreInitFinished!");
            }
        };

        if (!QbSdk.isTbsCoreInited()) {
            //x5内核初始化接口
            QbSdk.initX5Environment(this, cb);
        } else {
            createWebView();
        }
    }

    /**
     * 创建并初始化 X5 WebView 和 地图JS插件
     */
    private void createWebView() {

        if (webView != null)
            return;

        webView = new WebView(this);
        rootView.addView(webView, 0, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));

        WebSettings webSettings = webView.getSettings();
        webSettings.setDatabaseEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setGeolocationEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setMediaPlaybackRequiresUserGesture(false);

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (!url.startsWith("http")) {
                    try {
                        // 以下固定写法
                        final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                        startActivity(intent);
                    } catch (Exception e) { }
                    return true;
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
        });

        webView.setWebChromeClient(new WebChromeClient() {

            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissionsCallback callback) {
                final boolean remember = true;
                AlertDialog.Builder builder = new AlertDialog.Builder(MapWebViewX5PluginActivity.this);
                builder.setTitle("位置信息");
                builder.setMessage(origin + "允许获取您的地理位置信息吗？").setCancelable(true)
                        .setPositiveButton("允许", (dialog, id) -> callback.invoke(origin, true, remember))
                        .setNegativeButton("不允许", (dialog, id) -> callback.invoke(origin, false, remember));
                AlertDialog alert = builder.create();
                alert.show();
            }

            @Override
            public void onPermissionRequest(final PermissionRequest request) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MapWebViewX5PluginActivity.this);
                builder.setTitle("权限申请");
                StringBuilder sb = new StringBuilder();
                for (String s: request.getResources()) {
                    if (sb.length() != 0) {
                        sb.append(",");
                    }
                    if (s.equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) {
                        sb.append("录音");
                    } else if (s.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
                        sb.append("录相");
                    }
                }
                builder.setMessage("允许获取" + sb + "权限吗？").setCancelable(true)
                        .setPositiveButton("允许", (dialog, id) -> request.grant(request.getResources()))
                        .setNegativeButton("不允许", (dialog, id) -> request.deny());
                AlertDialog alert = builder.create();
                alert.show();
            }
        });

        //  创建并初始化 X5 JS 插件
        webViewPlugin = new BRTWebViewPlugin(this, new DefaultWebViewX5Delegate(webView)) {
            @Override
            protected void onRequestLocation() {
                checkBtNeedEnable();
            }
        };

        // 加载地图URL
        webView.loadUrl(url);
    }

    private void checkPermissions() {

            List<String> permissions = new ArrayList<>();

            //  X5引擎初始化权限
            permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);

            //  GPS和室内定位权限
            permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
            permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);

            //  二维码扫描功能
            permissions.add(Manifest.permission.CAMERA);

            // 如果页面需要调用语音转文字功能, 请移除下行代码注释
            //permissions.add(Manifest.permission.RECORD_AUDIO);

            // 安卓12及以上系统请添加以下权限声明，用于蓝牙打开和Beacon信标扫描
            if (Build.VERSION.SDK_INT >= 31) {
                permissions.add(Manifest.permission.BLUETOOTH_CONNECT);
                permissions.add(Manifest.permission.BLUETOOTH_SCAN);
            }

            List<String> checkPermissionList = new ArrayList<>();

            for (String permission: permissions) {
                if (this.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    checkPermissionList.add(permission);
                }
            }

            if (!checkPermissionList.isEmpty()) {
                requestPermissions(checkPermissionList.toArray(new String[1]), REQUEST_PLUGIN_PERMISSIONS);
                return;
            }

            initX5();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PLUGIN_PERMISSIONS) {
            //  权限申请完成
            initX5();
        }
    }

    private boolean checkBtNeedEnable() {
        final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (bluetoothAdapter == null)
            return false;

        if (bluetoothAdapter.isEnabled())
            return false;

        //  如果用户没有确认权限，就跳过打开蓝牙
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }

        //  请求打开蓝牙开关
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(intent, REQUEST_ENABLE_BT);
        return true;
    }

    private boolean checkGpsNeedEnable() {
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("提醒")
                .setMessage("定位功能将受限制：当前设备GPS未打开！是否确认打开GPS开关？")
                .setPositiveButton("确认", (dialog12, which) -> {
                    dialog12.dismiss();
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivityForResult(intent, REQUEST_ENABLE_GPS);
                })
                .setNegativeButton("忽略", (dialog1, which) -> dialog1.dismiss())
                .setCancelable(false)
                .create();
        dialog.getWindow().setGravity(Gravity.BOTTOM);
        dialog.show();
        return true;
    }

    private final BroadcastReceiver btStateBroadcastReceive = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
            if (blueState == BluetoothAdapter.STATE_ON) {
                checkGpsNeedEnable();
            }
        }
    };
}
